package com.yanqu.road.server.manager.gashapon;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.gashapon.data.GashaponNotice;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.bussiness.activity.GashaponBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.GashaponProto;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author : Cxp
 * @Time : 2024-10-21
 * @Description : 跨服幸运扭蛋Mgr
 */

public class CrossGashaponMgr extends TempCrossMgr {

    private static final Logger logger = LogManager.getLogger(CrossGashaponMgr.class);
    //活动id，公告数据列表
    private static final Map<Integer, List<GashaponNotice>> noticeDataMap = new ConcurrentHashMap<>();
    //需要插入数据库的公告数据列表
    private static final List<GashaponNotice> needInsertNoticeDataList = new ArrayList<>();
    //活动id，活动信息
    private static final Map<Integer, ActivityInfo> activityInfoMap = new ConcurrentHashMap<>();
    //活动id,消息体
    private static final Map<Integer, List<GashaponProto.GashaponNoticeDataTemp>> noticeMsgMap = new ConcurrentHashMap<>();


    @Override
    public boolean save() {
        if (needInsertNoticeDataList.isEmpty()) {
            return true;
        }
        List<GashaponNotice> tmpGashaponNoticeList = new ArrayList<>(needInsertNoticeDataList);
        needInsertNoticeDataList.clear();
        return GashaponBusiness.addNoticeDataList(tmpGashaponNoticeList);
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        // 读出当前正在进行的幸运扭蛋活动
        Map<Integer, ActivityInfo> tmpActivityMap = ActivityMgr.getOpenCrossActivityMapByType(eActivityType.Gashapon.getValue());
        activityInfoMap.putAll(tmpActivityMap);
        List<Integer> activityList = new ArrayList<>();

        for (Map.Entry<Integer, ActivityInfo> entry : activityInfoMap.entrySet()) {
            activityList.add(entry.getKey());
        }
        // 读出当前正在进行的幸运扭蛋活动的公告数据
        for (int activityId : activityList) {
            List<GashaponNotice> noticeDataList = GashaponBusiness.getNoticeDataList(activityId); // 先从新到旧 100个 排序
            noticeDataList.sort(Comparator.comparing(GashaponNotice::getNoticeTime)); // 按时间逆序
            noticeDataMap.put(activityId, noticeDataList);
            reGenerateNoticeMsg(activityId);
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean removeExpireData() throws Exception {
        List<Integer> acList = new ArrayList<>();
        long nowTime = System.currentTimeMillis();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            if (nowTime > activityInfo.getEndShowTime() * 1000 + 24 * 3600 * 1000) {
                acList.add(activityInfo.getActivityId());
            }
        }
        for (Integer activityId : acList) {
            noticeDataMap.remove(activityId);
            noticeMsgMap.remove(activityId);
            activityInfoMap.remove(activityId);
        }
        return true;
    }

    /**
     * 获取公告数据
     *
     * @param activityId 活动ID
     * @return GashaponNoticeMsgResp
     */
    public static GashaponProto.GashaponNoticeMsgResp.Builder getActivityNoticeMsg(int activityId) {
        GashaponProto.GashaponNoticeMsgResp.Builder builder = GashaponProto.GashaponNoticeMsgResp.newBuilder();
        if (getActivityInfo(activityId) == null) {
            builder.setRet(GameErrorCode.E_ACTIVITY_NOT_OPEN);
            return builder;
        }

        builder.setRet(0);
        if (noticeMsgMap.containsKey(activityId)) {
            builder.addAllNoticeDataList(noticeMsgMap.get(activityId));
        }

        return builder;
    }

    /**
     * 活动活动信息
     *
     * @param activityId 活动ID
     * @return ActivityInfo
     */
    public static ActivityInfo getActivityInfo(int activityId) {
        if (activityInfoMap.containsKey(activityId)) {
            return activityInfoMap.get(activityId);
        }
        synchronized (activityInfoMap) {
            if (activityInfoMap.containsKey(activityId)) {
                return activityInfoMap.get(activityId);
            }
            ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
            if (activityInfo == null) {
                activityInfo = ActivityBussiness.getActivityInfoByActivityId(activityId);
            }
            if (activityInfo != null) {
                activityInfoMap.put(activityId, activityInfo);
            }

        }
        return activityInfoMap.get(activityId);
    }

    /**
     * 将消息体转换成公告数据
     *
     * @param noticeData 协议公告信息
     * @return GashaponNotice
     */
    public static GashaponNotice parseMsgToNotice(GashaponProto.GashaponNoticeDataTemp noticeData) {
        GashaponNotice NoticeData = new GashaponNotice();
        NoticeData.setActivityId(noticeData.getActivityId());
        NoticeData.setUserId(noticeData.getUserId());
        NoticeData.setServerId(noticeData.getServerId());
        NoticeData.setNickName(noticeData.getNickName());
        NoticeData.setRewardType(noticeData.getType());
        NoticeData.setReward(noticeData.getReward());
        NoticeData.setNoticeTime(noticeData.getTime());

        return NoticeData;
    }

    /**
     * 将公告数据转换成消息体
     *
     * @param noticeData 公告信息
     * @return GashaponNoticeDataTemp
     */
    public static GashaponProto.GashaponNoticeDataTemp parseNoticeToMsg(GashaponNotice noticeData) {
        GashaponProto.GashaponNoticeDataTemp.Builder builder = GashaponProto.GashaponNoticeDataTemp.newBuilder();
        builder.setActivityId(noticeData.getActivityId());
        builder.setUserId(noticeData.getUserId());
        builder.setServerId(noticeData.getServerId());
        builder.setNickName(noticeData.getNickName());
        builder.setType(noticeData.getRewardType());
        builder.setReward(noticeData.getReward());
        builder.setTime(noticeData.getNoticeTime());

        return builder.build();
    }

    /**
     * 添加并上传公告
     *
     * @param activityId 活动ID
     * @param noticeData 公告列表
     * @param userId     用户ID
     */
    public static void addNotice(int activityId, List<GashaponProto.GashaponNoticeDataTemp> noticeData, long userId) {
        ActivityInfo activityInfo = getActivityInfo(activityId);
        if (activityInfo == null) {
            logger.error("CrossGashaponMgr add notice error,activityId = {} ,userId = {}", activityId, userId);
            return;
        }
        if (noticeData == null || noticeData.isEmpty()) {
            logger.error("CrossGashaponMgr add notice error,noticeData is null,activityId = {} ,userId = {}", activityId, userId);
            return;
        }

        // 广播公告
        GashaponProto.GashaponNoticeSyncMsg.Builder builder = GashaponProto.GashaponNoticeSyncMsg.newBuilder();
        builder.addAllNoticeList(noticeData);
        YanQuMessage yanQuMessage = YanQuMessageUtils.buildMessage(GameProtocol.S_GASHAPON_NOTICE_SYNC, builder);
        for (Long serverId : activityInfo.getServerIdList()) {
            MessageHelper.sendPacket(serverId, 0, yanQuMessage);
        }

        // 先加到消息里面
        synchronized (noticeMsgMap) {
            if (!noticeMsgMap.containsKey(activityId)) {
                noticeMsgMap.putIfAbsent(activityId, new ArrayList<>());
            }
            List<GashaponProto.GashaponNoticeDataTemp> noticeMsgList = noticeMsgMap.get(activityId);
            for (GashaponProto.GashaponNoticeDataTemp msg : noticeData) {
                if (noticeMsgList.size() >= 100) {
                    noticeMsgList.remove(0);
                }
                noticeMsgList.add(msg);
            }
        }
        // 再加到公告数据里面 顺便入库
        synchronized (noticeDataMap) {
            if (!noticeDataMap.containsKey(activityId)) {
                noticeDataMap.putIfAbsent(activityId, new ArrayList<>());
            }
            List<GashaponNotice> noticeDataList = noticeDataMap.get(activityId);
            for (GashaponProto.GashaponNoticeDataTemp msg : noticeData) {
                if (noticeDataList.size() >= 100) {
                    noticeDataList.remove(0);
                }
                GashaponNotice notice = parseMsgToNotice(msg);
                noticeDataList.add(notice);
                needInsertNoticeDataList.add(notice);
            }
        }
    }

    /**
     * 重新生成某个活动的公告数据
     *
     * @param activityId 活动ID
     */
    public static void reGenerateNoticeMsg(int activityId) {
        ActivityInfo activityInfo = getActivityInfo(activityId);
        if (activityInfo == null) {
            logger.error("CrossGashaponMgr reGenerateNoticeMsg error,activity no found, activityId = {} ", activityId);
            return;
        }
        List<GashaponNotice> noticeDataList = noticeDataMap.getOrDefault(activityId, new ArrayList<>());
        List<GashaponProto.GashaponNoticeDataTemp> noticeMsgList = new ArrayList<>();
        for (GashaponNotice data : noticeDataList) {
            GashaponProto.GashaponNoticeDataTemp noticeMsgData = parseNoticeToMsg(data);
            noticeMsgList.add(noticeMsgData);
        }
        synchronized (noticeMsgMap) {
            noticeMsgMap.put(activityId, noticeMsgList);
        }
    }
}
